/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.persistencia.dao.impl;

import com.persistencia.dao.EntidadDao;
import com.util.JPAutil;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;

/**
 * 
 * @author kenny
 */
public class EntidadDaoImpl<E> implements EntidadDao<E> {

	EntityManagerFactory emf;
	EntityManager em;
	JPAutil jpaUtil;

	protected E instance;
	private Class<E> entityClass;

	public EntidadDaoImpl() {
		jpaUtil = new JPAutil();
		emf = jpaUtil.getEmf();
		em = jpaUtil.getEm();
	}

	public EntityManager getEntityManager() {
		return em;
	}

	@Override
	public void registrar(E e) throws Exception {
		em.getTransaction().begin();
		em.persist(e);
		em.getTransaction().commit();
	}

	@Override
	public void actualizar(E e) throws Exception {
		em = getEntityManager();
		em.getTransaction().begin();
		em.merge(e);
		em.getTransaction().commit();
	}

	@Override
	public void eliminar(Object id) throws Exception {
		E e = obtenerPorId(id);
		getEntityManager().getTransaction().begin();
		getEntityManager().remove(e);
		getEntityManager().getTransaction().commit();
	}

	@Override
	public E obtenerPorId(Object id) throws Exception {
		return (E) getEntityManager().find(getEntityClass(), id);
	}

	@Override
	public List<E> obtenerLista() throws Exception {

		/*
		 * System.out.println("Nombre"+getEntityClass().getName()); String hql =
		 * "select e from " + getEntityClass().getName()+" e"; Query query =
		 * getEntityManager().createQuery(hql); return query.getResultList();
		 */
		try {
			System.out.println("Entidad" + getEntityClass());
			System.out.println("Entidad" + getEntityClass().getClass());
			// System.out.println("Docente.class "+Docente.class);
			CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
			cq.select(cq.from(getEntityClass()));
			// cq.select(cq.from(Docente.class));
			Query q = em.createQuery(cq);
			return q.getResultList();
		} finally {

		}
		// List<Docente> a = new A;
		// return (List<E>) a;
	}

	public Class<E> getEntityClass() throws Exception {
		if (entityClass == null) {
			Type type = getClass().getGenericSuperclass();
			if (type instanceof ParameterizedType) {
				ParameterizedType paramType = (ParameterizedType) type;
				if (paramType.getActualTypeArguments().length == 2) {
					if (paramType.getActualTypeArguments()[1] instanceof TypeVariable) {
						throw new IllegalArgumentException(
								"No se puede obtener clase mediante reflection");
					} else {
						entityClass = (Class<E>) paramType
								.getActualTypeArguments()[1];
					}
				} else {
					entityClass = (Class<E>) paramType.getActualTypeArguments()[0];
				}
			} else {
				throw new Exception(
						"No se puede obtener clase mediante reflection");
			}
		}
		return entityClass;
	}

}
